package com.my.algorithmlearning.leetcode;

import com.my.algorithmlearning.entity.ListNode;
import org.springframework.util.Assert;

import java.util.HashSet;
import java.util.Set;

/**
 * @ClassName ListNodeHasCycle
 * @Description ListNodeHasCycle
 * @Author wanghaiwei
 * @Date 2022/11/29 15:24
 */
public class ListNodeHasCycle {
    public boolean hasCycleHashSet(ListNode head) {
        Set<ListNode> existsNode = new HashSet<>();
        while(head != null) {
            if (!existsNode.add(head)) {
                return true;
            }
            head = head.next;
        }
        return false;
    }

    public boolean hasCycleFastSlowRef(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (slow == fast) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        ListNodeHasCycle solution = new ListNodeHasCycle();
        ListNode root1 = new ListNode(3);
        root1.next = new ListNode(2);
        root1.next.next = new ListNode(0);
        root1.next.next.next = new ListNode(-4);
        root1.next.next.next.next = root1.next;
        Assert.isTrue(solution.hasCycleHashSet(root1), "head = [3,2,0,-4], pos = 1 hasCycleHashSet结果错误");

        ListNode root2 = new ListNode(1);
        root2.next = new ListNode(2);
        root2.next.next = root2;
        Assert.isTrue(solution.hasCycleHashSet(root2), "head = [1,2], pos = 0 hasCycleHashSet结果错误");

        ListNode root3 = new ListNode(1);
        Assert.isTrue(!solution.hasCycleHashSet(root3), "head = [1], pos = -1 hasCycleHashSet结果错误");

        ListNode root21 = new ListNode(3);
        root21.next = new ListNode(2);
        root21.next.next = new ListNode(0);
        root21.next.next.next = new ListNode(-4);
        root21.next.next.next.next = root21.next;
        Assert.isTrue(solution.hasCycleFastSlowRef(root21), "head = [3,2,0,-4], pos = 1 hasCycleFastSlowRef结果错误");

        ListNode root22 = new ListNode(1);
        root22.next = new ListNode(2);
        root22.next.next = root22;
        Assert.isTrue(solution.hasCycleFastSlowRef(root22), "head = [1,2], pos = 0 hasCycleFastSlowRef结果错误");

        ListNode root23 = new ListNode(1);
        Assert.isTrue(!solution.hasCycleFastSlowRef(root23), "head = [1], pos = -1 hasCycleFastSlowRef结果错误");
    }
}
